#include "../source/server.hpp"

//这是Socket类Server的测试

/*
void HandleClose(Channel *channel)
{
    DBG_LOG("close fd:%d",channel->Fd());
    channel->Remove(); //移除监控
    delete channel;
}
*/

/*
void HandleRead(Channel *channel)
{
    int fd=channel->Fd();
    char buf[1024]={0};
    int ret=recv(fd,buf,1023,0);
    if(ret<=0)
    {
        return HandleClose(channel); //关闭释放
    }
    DBG_LOG("%s",buf);
    channel->EnableWrite(); //启动可写事件
}
*/

/*
void HandleWrite(Channel *channel)
{
    int fd=channel->Fd();
    const char *data="今天吃的什么？";
    int ret=send(fd,data,strlen(data),0);
    if(ret<0)
    {
        return HandleClose(channel); //关闭释放
    }
    channel->DisableWrite(); //关闭写监控
}
*/

/*
void HandleError(Channel *channel)
{
    return HandleClose(channel); //关闭释放
}

void HandleEvent(EventLoop *loop, Channel *channel, uint64_t timerid)
{ 
    loop->TimerRefresh(timerid);
    //std::cout<<"有一个事件!"<<std::endl;
}
*/

//管理所有的连接对象
std::unordered_map<uint64_t,PtrConnection> _conns; 
uint64_t conn_id=0;//rand()%10000;
//EventLoop loop;
EventLoop base_loop;
//std::vector<LoopThread> threads(2);
//int next_loop=0;
LoopThreadPool *loop_pool;

void ConnectDestroy(const PtrConnection &conn) //对连接对象的销毁
{
    _conns.erase(conn->Id());
}
//打印连接信息
void OnConnected(const PtrConnection &conn)
{
    DBG_LOG("NEW CONNECTION:%p",conn.get());
}

//打印信息
void OnMessage(const PtrConnection &conn, Buffer *buf)
{
    DBG_LOG("%s",buf->GetReadPosition());
    buf->MoveReadOffset(buf->GetReadAbleSize());
    std::string str="Hello OnMessage";
    conn->Send(str.c_str(),str.size());
}

void NewConnection(int fd)
{
    //int fd=lst_channel->Fd(); //获取我们的套接字
    //int newfd=accept(fd,NULL,NULL);
    //if(newfd<0) {return;}

    conn_id++;
    //next_loop=(next_loop+1)%2;
    PtrConnection conn(new Connection(loop_pool->NextLoop()/*threads[next_loop].GetLoop()*/,conn_id,fd));
    conn->SetMessageCallback(std::bind(OnMessage,std::placeholders::_1,std::placeholders::_2)); //为通信套接字设置可读事件的回调函数
    //channel->SetWriteCallback(std::bind(HandleWrite,channel)); //可读事件的回调函数
    conn->SetSrvClosedCallback(std::bind(ConnectDestroy,std::placeholders::_1)); //关闭事件的回调函数
    conn->SetConnectedCallback(std::bind(OnConnected,std::placeholders::_1)); //错误事件的回调函数
    //conn->SetAnyEventCallback(std::bind(HandleEvent,conn)); //任意事件的回调函数

    //启动十秒后的销毁
    conn->EnableInactiveRelease(10); //启动非活跃超时销毁
    conn->Established(); //就绪初始化

    //非活跃连接的超时释放操作
    //定时销毁任务，必须在读事件之前，因为有可能启动了事件监控后，立即就有了事件，但这时还没有任务
    //loop->TimerAdd(timerid,10,std::bind(HandleClose,channel)); //添加一个定时器，每十秒进行一次释放
    //channel->EnableRead();

    //插入到我们的unordered_map中
    _conns.insert(std::make_pair(conn_id,conn));
}

int main()
{
    loop_pool=new LoopThreadPool(&base_loop);
    loop_pool->SetThreadCount(2);
    loop_pool->Create();

    srand(time(NULL)); //获取随机数种子
    //Poller poller;
    //EventLoop loop;
    //Socket lst_sock;
    //lst_sock.CreateServer(8500);
    Acceptor acceptor(&base_loop,8500);
    //为了监听套接字，我们创建一个Channel进行事件的管理
    //Channel channel(&loop,lst_sock.Fd());
    //channel.SetAcceptCallback(std::bind(Acceptor,&loop,&channel)); //回调中，获取新连接，为新连接创建channel并且添加监控
    acceptor.SetAcceptCallback(std::bind(NewConnection,std::placeholders::_1)); 
    //acceptor.EnableRead(); //启动可读事件监控
    acceptor.Listen(); 
    base_loop.Start();
    /*while(1)
    {
        base_loop.Start();
        /
        std::vector<Channel*> actives; //创建一个活跃连接
        poller.Poll(&actives); 
        for(auto &a:actives) //遍历获取获取活跃连接
        {
            std::cout<<"-----------------"<<std::endl;
            a->HandleEvent(); //根据事件的类型进行不同的事件处理
            //HandleEvent(a);
        }
        sleep(1);
        /
    }
    */
    //lst_sock.Close();
    return 0;
}

/*
//这是Socket类Server的测试
int main()
{
    Socket lst_sock;
    lst_sock.CreateServer(8500);
    while(1)
    {
        int newfd=lst_sock.Accept();
        if(newfd<0)
        {
            sleep(1);
            continue;
        }
        Socket cli_sock(newfd);
        char buf[1024]={0};
        int ret=cli_sock.Recv(buf,1023); 
        if(ret<0)
        {
            cli_sock.Close();
            continue;
        }
        cli_sock.Send(buf,ret);
        cli_sock.Close();
    }
    lst_sock.Close();
    return 0;
}
*/